<template>
  <div>
    <a-form @submit="handleSubmit" :form="form">
      <a-card class="card" title="供应商信息" :bordered="false">
        <a-form-item
          required
          label="供应商"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
        >
          <supplier-select
            v-decorator="['supplier_id', { rules: [{ required: true, message: '请选择供应商' }], initialValue: null}]"></supplier-select>
        </a-form-item>
        <a-form-item
          required
          label="产品供价"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
        >
          <a-select
            v-decorator="['offer_price', { rules: [{ required: true, message: '请选择产品供价' }]}]"
            placeholder="请选择"
          >
            <a-select-option value="1">代发</a-select-option>
            <a-select-option value="2">含运费到仓</a-select-option>
            <a-select-option value="3">裸价</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item
          required
          label="产品货源"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
        >
          <a-select
            v-decorator="['supply', { rules: [{ required: true, message: '请选择产品货源' }]}]"
            placeholder="请选择"
          >
            <a-select-option value="1">品牌</a-select-option>
            <a-select-option value="2">代工厂</a-select-option>
            <a-select-option value="3">仿货</a-select-option>
            <a-select-option value="4">其他</a-select-option>
          </a-select>
        </a-form-item>
      </a-card>

      <a-card class="card" title="基本信息" :bordered="false">
        <!--        <a-form-item-->
        <!--          label="商品编号"-->
        <!--          :labelCol="labelCol"-->
        <!--          :wrapperCol="wrapperCol"-->
        <!--        >-->
        <!--          <a-input-->
        <!--            v-decorator="['numbering', {rules: [{ required: true, message: '请输入商品编号' }]}]"-->
        <!--            name="name"-->
        <!--            placeholder="请输入商品编号"/>-->
        <!--        </a-form-item>-->

        <a-form-item
          label="商品名称"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
        >
          <a-input
            v-decorator="['name', {rules: [{ required: true, message: '请输入商品名称' }]}]"
            name="name"
            placeholder="请输入商品名称"/>
        </a-form-item>

        <a-form-item
          label="商品类别"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
        >
          <commodity-category-selection
            v-decorator="['category_id', {rules: [{ required: true, message: '请选择商品类别' }], initialValue: null }]"
          />
        </a-form-item>

        <a-form-item
          required
          label="商品组图"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
        >
          <upload-pic
            :limit="5"
            tips="建议尺寸640 x 640 像素，"
            v-decorator="['attachment_ids',{ rules: [{ required: true, message: '请上传 SKU 组图' }], initialValue: null}]"
          />
        </a-form-item>
      </a-card>

      <a-card class="card" title="规格信息 (SKU)" :bordered="false">
        <a-form-item
          label="规格设置"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
        >

          * 可设置颜色、尺码等，目前最多仅支持编辑2个规格。
          <a-form-item v-for="(k, skuSpecificationIndex) in skuSpecification" :required="false" :key="k">
            <a-input
              v-decorator="[`multiple_specification[${k}]`, {}]"
              :ref="`multiple_specification_${k}`"
              placeholder="请填写规格名称"
              style="width: 60%; margin-right: 8px"
              @blur="refreshMultipleSpecification"
            />
            <a-icon
              v-if="skuSpecification.length > 1"
              class="dynamic-delete-button"
              type="minus-circle-o"
              :disabled="skuSpecification.length === 1"
              @click="() => removeSpecification(k)"
            />

            <a-form-item>
              <template v-for="detail in skuSpecificationDetail[k]">
                <a-popover
                  v-if="skuSpecificationIndex === 0"
                  :key="detail"
                  trigger="click"
                >
                  <div slot="content">
                    <upload-pic
                      :limit="1"
                      v-if="skuSpecificationInitialPicture.hasOwnProperty(k) && skuSpecificationInitialPicture[k].hasOwnProperty(detail)"
                      v-model="skuSpecificationInitialPicture[k][detail]"
                      @change="picRes => handleSkuPictureChange(k, detail, picRes)"
                    />
                  </div>

                  <a-tag
                    :closable="true"
                    @close="removeSkuSpecificationDetail(detail, k)"
                  >
                    <span
                      v-if="skuSpecificationPicture.hasOwnProperty(k) && skuSpecificationPicture[k].hasOwnProperty(detail) && Object.keys(skuSpecificationPicture[k][detail]).length > 0"
                    >
                      <img
                        :src="skuSpecificationPicture[k][detail].url"
                        width="50"
                        height="50"
                        style="display: inline"
                      />
                    </span>
                    <span v-else>
                      <a-icon type="picture"/>
                    </span>
                    {{ detail }}
                  </a-tag>
                </a-popover>
                <a-tag
                  v-else
                  :key="detail"
                  :closable="true"
                  @close="removeSkuSpecificationDetail(detail, k)"
                >
                  {{ detail }}
                </a-tag>
              </template>
              <a-input
                v-if="skuSpecificationInputVisible[k]"
                :ref="'skuSpecificationInput_' + k"
                type="text"
                size="small"
                :style="{ width: '78px' }"
                :value="skuSpecificationDetailInputValue"
                @change="handleSkuSpecificationDetailChange"
                @blur="handleSkuSpecificationDetailConfirm(k)"
              />
              <a-tag
                v-else
                style="background: #fff; borderStyle: dashed;"
                @click="showSkuSpecificationDetailInput(k)"
              >
                <a-icon type="plus"/>
                新增明细
              </a-tag>
            </a-form-item>
          </a-form-item>
          <a-form-item v-if="skuSpecification.length < skuSpecificationLimit">
            <a-button type="dashed" style="width: 60%" @click="addSpecification">
              <a-icon type="plus"/>
              添加规格
            </a-button>
          </a-form-item>
        </a-form-item>

        <a-form-item
          required
          label="规格信息"
          :labelCol="labelCol"
          rowKey="id"
        >
          <sku-table
            v-model="skuSpecificationDetailTableValue"
            :extra-columns="skuSpecificationInformationColumns"
            :multiple-specification="multipleSpecification"
            :multiple-specification-detail="skuSpecificationDetail"
          />
        </a-form-item>
      </a-card>

      <footer-tool-bar
        :style="{ width: isSideMenu() && isDesktop() ? `calc(100% - ${sidebarOpened ? 256 : 80}px)` : '100%'}">
        <a-button htmlType="submit" type="primary" :loading="loading">保存</a-button>
      </footer-tool-bar>
    </a-form>
  </div>
</template>

<script>
  import FooterToolBar from '@/components/FooterToolbar'
  import { mixin, mixinDevice } from '@/utils/mixin'
  import Vue from 'vue'
  import SupplierSelect from '@/components/SupplierSelect/SupplierSelect'
  import UploadPic from '@/components/UploadPic/UploadPic'
  import { getCommodityInfo, saveCommodity } from '@/api/commodity'
  import CommodityCategorySelection from '@/components/CommodityCategorySelection/CommodityCategorySelection'
  import SkuTable from '@/components/SkuTable/SkuTable'
  import { cloneDeep, forIn, pick } from 'lodash'

  let selfIncreasingId = 4 // 2 和 3 的 id 会报 warn key 重复, 不细查了, 跳过 2 3 从 4 开始
  const baseColumns = [
    {
      title: '入仓价（元）',
      width: '25%',
      scopedSlots: { customRender: 'entry_price' }
    },
    {
      title: '进价（元）',
      width: '25%',
      scopedSlots: { customRender: 'purchase_price' }
    }
  ]

  export default {
    name: 'Form',
    mixins: [mixin, mixinDevice],
    components: {
      SkuTable,
      CommodityCategorySelection,
      UploadPic,
      SupplierSelect,
      FooterToolBar
    },
    data () {
      return {
        labelCol: {
          xs: { span: 2 },
          sm: { span: 2 }
        },
        wrapperCol: {
          xs: { span: 8 },
          sm: { span: 8 }
        },
        form: this.$form.createForm(this),

        multipleSpecification: {},

        skuSpecificationLimit: 2,
        skuSpecificationInputVisible: [],
        skuSpecification: [],
        skuSpecificationInitialPicture: {}, // 规格上传图片 初始化用
        skuSpecificationPicture: {}, // 规格图片
        skuSpecificationDetail: {},
        skuSpecificationDetailInputValue: '',
        skuSpecificationDetailExtendedInputValues: [],
        loading: false,

        skuSpecificationInformationColumns: baseColumns,
        skuSpecificationDetailTableValue: [],

        commodityInfo: {}
      }
    },
    methods: {
      handleSubmit (e) {
        e.preventDefault()
        this.loading = true
        this.form.validateFields((err, values) => {
          if (err) {
            this.loading = false
            return
          }

          // 编辑
          if (this.$route.params.id) {
            values.id = this.$route.params.id
          }

          values.attachment_ids = values.attachment_ids.map(item => item.response.id) // 处理商品组图格式
          // 处理 sku value 数据
          const tableValue = []
          this.skuSpecificationDetailTableValue.forEach(item => {
            var itemTemp = cloneDeep(item)
            itemTemp.entry_price = itemTemp.entry_price * 100 // 后端单位 分
            itemTemp.purchase_price = itemTemp.purchase_price * 100
            // 遍历 sku 分配附件 ID 给 tableValue sku picture
            forIn(this.skuSpecificationPicture, (pictureItem, pictureKey) => {
              forIn(pictureItem, (picture, detail) => {
                if (itemTemp[pictureKey] === detail) {
                  itemTemp['sku_picture'] = picture.id
                }
              })
            })

            tableValue.push(itemTemp)
          })

          // 处理 sku 规格, 这里提交的时候 单独加上 sku 组图, 也不影响其他地方
          const skuSpecificationDetail = cloneDeep(this.skuSpecificationDetail)
          // 遍历 sku 分配给 tableValue sku picture
          const firstSpecificationDetailKey = Object.keys(skuSpecificationDetail)[0] // 只有第一规格才有图片,所以这里只取第一个规格的 key
          // 把第一规格数据替换掉
          skuSpecificationDetail[firstSpecificationDetailKey] = skuSpecificationDetail[firstSpecificationDetailKey].map(value => {
            if (this.skuSpecificationPicture.hasOwnProperty(firstSpecificationDetailKey) && this.skuSpecificationPicture[firstSpecificationDetailKey].hasOwnProperty(value)) {
              return {
                // 给加上附件 ID
                'sku_picture': this.skuSpecificationPicture[firstSpecificationDetailKey][value].id,
                value
              }
            }

            return {
              value
            }
          })

          saveCommodity(Object.assign(values, {
            specification: this.form.getFieldValue('multiple_specification'),
            specification_detail: skuSpecificationDetail,
            specification_value: tableValue
          }))
            .then(res => {
              this.$message.success('保存成功!')
              this.$router.push('/commodity/commodity/list')
            })
            .finally(_ => {
              this.loading = false
            })
        })
      },
      /**
       * 增加规格
       * @returns {boolean}
       */
      addSpecification () {
        if (this.skuSpecification.length >= this.skuSpecificationLimit) {
          return false
        }

        // 明细
        const currentSelfIncreasingId = selfIncreasingId
        Vue.set(this.skuSpecificationDetail, currentSelfIncreasingId, [])
        Vue.set(this.skuSpecificationInputVisible, currentSelfIncreasingId, false)

        // 规格
        this.skuSpecification = this.skuSpecification.concat(selfIncreasingId++)

        this.$nextTick(_ => this.$refs[`multiple_specification_${currentSelfIncreasingId}`][0].focus())
      },
      /**
       * 减少规格
       * @param k
       */
      removeSpecification (k) {
        if (this.skuSpecification.length === 1) {
          return
        }

        Vue.delete(this.skuSpecification, this.skuSpecification.indexOf(k))
        Vue.delete(this.skuSpecificationDetail, k) // 删除明细
        Vue.delete(this.form.formItems, `multiple_specification[${k}]`) // 删除表单注册

        this.$nextTick(_ => this.refreshMultipleSpecification())
      },
      /**
       * 刷新规格值
       */
      refreshMultipleSpecification () {
        const current = this.form.getFieldsValue()['multiple_specification']
        // 减少的
        Object.keys(this.multipleSpecification).forEach(index => {
          if (!current.hasOwnProperty(index)) {
            Vue.delete(this.multipleSpecification, index)
          }
        })

        // 新增的
        current && current.forEach((item, index) => {
          Vue.set(this.multipleSpecification, index, item)
        })
      },
      /**
       * 规格详情的输入事件
       * @param e
       */
      handleSkuSpecificationDetailChange (e) {
        this.skuSpecificationDetailInputValue = e.target.value
      },
      /**
       * 规格详情 输入确认
       * @param k
       */
      handleSkuSpecificationDetailConfirm (k) {
        const inputValue = this.skuSpecificationDetailInputValue
        const details = this.skuSpecificationDetail[k]
        if (inputValue && details.indexOf(inputValue) === -1) {
          const resultInputValue = [...details, inputValue]
          Vue.set(this.skuSpecificationDetail, k, resultInputValue)
          // 规格图片 v-model 初始化
          !this.skuSpecificationInitialPicture.hasOwnProperty(k) && Vue.set(this.skuSpecificationInitialPicture, k, {})
          !this.skuSpecificationInitialPicture[k].hasOwnProperty(inputValue) && Vue.set(this.skuSpecificationInitialPicture[k], inputValue, [])
        }
        Vue.set(this.skuSpecificationInputVisible, k, false)
        this.skuSpecificationDetailInputValue = ''
      },
      /**
       * 展示规格详情输入框
       * @param k
       */
      showSkuSpecificationDetailInput (k) {
        Vue.set(this.skuSpecificationInputVisible, k, true)
        this.$nextTick(_ => this.$refs[`skuSpecificationInput_${k}`][0].focus())
      },
      /**
       * 移除规格详情输入框
       * @param detail
       * @param k
       */
      removeSkuSpecificationDetail (detail, k) {
        const detailList = this.skuSpecificationDetail[k].filter(value => value !== detail)
        Vue.set(this.skuSpecificationDetail, k, detailList)
      },
      /**
       * 规格图片
       * @param k
       * @param detail
       * @param picRes
       */
      handleSkuPictureChange (k, detail, picRes) {
        if (!this.skuSpecificationPicture.hasOwnProperty(k)) {
          Vue.set(this.skuSpecificationPicture, k, {})
        }

        // 存储规格图片 ID
        const picList = picRes.filter(pic => pic.status === 'done')
        if (picList.length === 0) {
          Vue.set(this.skuSpecificationPicture[k], detail, {})
          return false
        }

        Vue.set(this.skuSpecificationPicture[k], detail, pick(picList[0].response, ['id', 'url']))
      }
    },
    created () {
      const { form } = this

      if (this.$route.params.id) {
        getCommodityInfo(this.$route.params.id).then(res => {
          this.commodityInfo = res

          // 初始化表单
          form.setFieldsValue({
            // numbering: res.numbering,
            name: res.name,
            category_id: res.category_id,
            attachment_ids: res.attachments.map(att => {
              return {
                response: {
                  url: att.url,
                  id: att.id
                },
                mime_type: att.mime_type || '',
                name: att.id.toString(),
                url: att.url,
                uid: att.id
              }
            }),
            supplier_id: res.supplier.id,
            offer_price: res.offer_price.toString(),
            supply: res.supply.toString()
          })

          // 初始化 规格设置
          const attributeIdMap = {} // 这里用来对应 attribute.id 对应 selfIncreasingId, 不然直接用 attribute.id 的话对象内容太大
          res.attributes.forEach((attribute, index) => {
            attributeIdMap[attribute.id] = selfIncreasingId
            // 初始化 sku 图片, 这里用 index 为零作为第一规格判断依据
            if (index === 0) {
              if (!this.skuSpecificationPicture.hasOwnProperty(selfIncreasingId)) {
                Vue.set(this.skuSpecificationPicture, selfIncreasingId, {})
              }
              attribute.values.forEach(value => {
                // 初始化 上传图片组件需要的值
                if (!this.skuSpecificationInitialPicture.hasOwnProperty(selfIncreasingId)) {
                  Vue.set(this.skuSpecificationInitialPicture, selfIncreasingId, {})
                }
                Vue.set(this.skuSpecificationInitialPicture[selfIncreasingId], value.content, [])

                if (value.attachments.length > 0) {
                  Vue.set(this.skuSpecificationPicture[selfIncreasingId], value.content, pick(value.attachments[0], ['id', 'url']))
                  const { id, url } = pick(value.attachments[0], ['id', 'url'])

                  Vue.set(this.skuSpecificationInitialPicture[selfIncreasingId], value.content, [
                    {
                      response: {
                        url: url,
                        id: id
                      },
                      mime_type: value.attachments[0].mime_type || '',
                      name: id.toString(),
                      url: url,
                      status: 'done',
                      uid: id
                    }
                  ])
                }
              })
            }

            Vue.set(this.skuSpecificationDetail, attributeIdMap[attribute.id], [])
            Vue.set(this.skuSpecificationInputVisible, attributeIdMap[attribute.id], false)
            // 规格
            this.skuSpecification = this.skuSpecification.concat(selfIncreasingId++)
            // 规格明细
            Vue.set(this.skuSpecificationDetail, attributeIdMap[attribute.id], attribute.values.map(value => value.content))
            // 规格的内容(名字)
            this.$nextTick(_ => {
              form.setFieldsValue({
                [`multiple_specification[${attributeIdMap[attribute.id]}]`]: attribute.name
              })
            })
          })

          // 初始化 表格内容
          res.skus.forEach((sku, index) => {
            sku.values.forEach(item => {
              sku[attributeIdMap[item.attribute_id]] = item.content
            })

            // 格式化价格 (后端价格单位为分)
            sku.entry_price /= 100
            sku.purchase_price /= 100

            Vue.set(this.skuSpecificationDetailTableValue, index, sku)
          })

          this.$nextTick(_ => {
            this.refreshMultipleSpecification()
          })
        })
      }
    }
  }
</script>

<style lang="less" scoped>
  .card {
    margin-bottom: 24px;

    &:last-child {
      margin-bottom: 80px;
    }
  }

  .dynamic-delete-button {
    cursor: pointer;
    position: relative;
    top: 4px;
    font-size: 24px;
    color: #999;
    transition: all 0.3s;
  }

  .dynamic-delete-button:hover {
    color: #777;
  }

  .dynamic-delete-button[disabled] {
    cursor: not-allowed;
    opacity: 0.5;
  }
</style>
